<template>
  <div
    ref="target"
    class="TextInput w-full relative rounded-lg select-none heading-s-medium"
  >
    <div
      class="flex items-center gap-2.5 outline outline-1 rounded-lg px-4 py-2 hover:outline-c-grey-large bg-c-white"
      :class="[
        { 'outline-c-grey-xs': !focused },
        { 'outline-c-grey-large': focused }
      ]"
    >
      <SvgoSearchIcon filled />
      <AtomInput
        ref="focusTarget"
        type="text"
        :placeholder="placeholder"
        :value="modelValue"
        @input="updateValue"
      />
      <SvgoCloseIcon
        v-if="modelValue"
        class="cursor-pointer text-c-grey-medium hover:text-c-grey-large mt-0.5"
        filled
        @click="$emit('update:modelValue', '')"
      />
    </div>
    <div
      v-if="showSearchVariants && modelValue && activeSearchResults"
      class="absolute bg-c-white flex flex-col w-full z-10 shadow-dropdown-s rounded-xl px-2 pr-0.5 py-2 mt-1 max-h-72 overflow-y-hidden overflow-x-auto"
    >
      <div
        v-if="computedSearchVariants.length > 0"
        ref="searchSelectionVariantsRef"
        class="overflow-y-auto pr-4"
      >
        <div
          v-for="variant in computedSearchVariants"
          :key="variant.id"
          class="heading-s-medium text-c-grey-2xl hover:text-c-grey-3xl cursor-pointer py-1.5 px-3 hover:bg-c-grey-xs rounded-xl"
          @click="handleCLickVariant(variant)"
        >
          <div v-if="showPhotoInSearhVariants">
            <AtomSearchVariantWithPhoto :id="variant.id">
              {{
                Array.isArray(searchField)
                  ? variant[`${searchField[0]}`] +
                    ' ' +
                    variant[`${searchField[1]}`]
                  : variant[`${searchField}`]
              }}
            </AtomSearchVariantWithPhoto>
          </div>
          <div v-else>
            {{
              Array.isArray(searchField)
                ? variant[`${searchField[0]}`] +
                  ' ' +
                  variant[`${searchField[1]}`]
                : variant[`${searchField}`]
            }}
          </div>
        </div>
      </div>
      <div v-else class="heading-s-medium text-c-grey-large pl-3">
        Ничего не найдено
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import filter from 'lodash.filter'
interface Props {
  placeholder: string
  showSearchVariants?: boolean
  searchVariants?: any[]
  searchField?: string | string[] // max arr length = 2
  modelValue: string
  showPhotoInSearhVariants?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  placeholder: 'Input something',
  showSearchVariants: false,
  searchVariants: () => [],
  searchField: '',
  modelValue: '',
  showPhotoInSearhVariants: false
})
const emit = defineEmits(['update:modelValue', 'chooseVariant'])
const {
  placeholder,
  showSearchVariants,
  searchVariants,
  modelValue,
  searchField,
  showPhotoInSearhVariants
} = toRefs(props)
const focusTarget = ref()
const { focused } = useFocus(focusTarget)
const activeSearchResults = ref(true)
const searchSelectionVariantsRef = ref(null)

const { arrivedState } = useScroll(searchSelectionVariantsRef)
const { bottom } = toRefs(arrivedState)
const pageSize = 7
const lastPage = computed(() =>
  Math.ceil(searchVariants.value.length / pageSize)
)
const nextPage = ref(2)
const target = ref(null)

const updateValue = (e: Event) => {
  activeSearchResults.value = true
  emit('update:modelValue', (e.target as HTMLInputElement).value)
}
const handleCLickVariant = (variant: any) => {
  activeSearchResults.value = false
  if (Array.isArray(searchField.value)) {
    emit(
      'update:modelValue',
      variant[`${searchField.value[0]}`] +
        ' ' +
        variant[`${searchField.value[1]}`]
    )
    emit('chooseVariant', variant)
  } else {
    emit('update:modelValue', variant[`${searchField.value}`])
    emit('chooseVariant', variant)
  }
}

const computedSearchVariants = computed(() => {
  if (modelValue.value) {
    const input = modelValue.value
      .toLowerCase()
      .trim()
      .split(' ')
      .filter(Boolean)
    return filter(searchVariants.value, (o: any) => {
      if (o[searchField.value[0]] && o[searchField.value[1]]) {
        if (Array.isArray(searchField.value)) {
          if (!input[1]) {
            return (
              o[searchField.value[0]].toLowerCase().includes(input[0]) ||
              o[searchField.value[1]].toLowerCase().includes(input[0])
            )
          }
          return (
            (o[searchField.value[0]].toLowerCase().includes(input[0]) ||
              o[searchField.value[1]].toLowerCase().includes(input[0])) &&
            (o[searchField.value[0]].toLowerCase().includes(input[1]) ||
              o[searchField.value[1]].toLowerCase().includes(input[1]))
          )
        } else {
          return (
            o[searchField.value].toLowerCase().includes(input[0]) ||
            o[searchField.value].toLowerCase().includes(input[1])
          )
        }
      } else {
        return false
      }
    }).slice(0, pageSize * (nextPage.value - 1))
  } else return []
})

// достигли дна - подгружаем новые данные списка
watch(bottom, () => {
  if (bottom.value) {
    if (nextPage.value < lastPage.value) {
      nextPage.value += 1
    }
  }
})

// если выпадашка размонтируется - очищаем список подгруженных опций
watch(searchSelectionVariantsRef, () => {
  if (!searchSelectionVariantsRef.value) {
    nextPage.value = 2
  }
})

// закрываем выпадашку при клике снаружи
onClickOutside(target, () => {
  activeSearchResults.value = false
})
</script>

<style lang="scss" scoped>
$component: '.TextInput';
</style>
